package gob.cgr.web.sgrh.managed;

import gob.cgr.sgrh.ejb.entidad.AdmGrado;
import gob.cgr.sgrh.ejb.entidad.Cargo;
import gob.cgr.sgrh.ejb.entidad.CondicionEstudio;
import gob.cgr.sgrh.ejb.entidad.Puesto;
import gob.cgr.sgrh.ejb.entidad.PuestoAnalisis;
import gob.cgr.sgrh.ejb.entidad.PuestoCabecera;
import gob.cgr.sgrh.ejb.entidad.PuestoCapacitacion;
import gob.cgr.sgrh.ejb.entidad.PuestoEducacion;
import gob.cgr.sgrh.ejb.entidad.UnidadOrganica;
import gob.cgr.web.sgrh.service.SigerhService;
import gob.cgr.web.sgrh.util.Utilitario;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import javax.inject.Inject;

import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

@ManagedBean
@ViewScoped
public class PuestoUnidadMB {
	private DefaultTreeNode arbolUO;
	private List<UnidadOrganica> unidadesOrganicasList;
	private UnidadOrganica uoSelected;
	private TreeNode nodeUOSelected;
	private TreeNode nodePuestoSelected;
	private Puesto puestoSelected;
	private Puesto puestoEdicionSelected;
	private String mision;
	private String funciones;
	private String nroHojaInformativa;
	private boolean disponibilidadViaje;
	private DefaultTreeNode arbolPuestosUO;
	private PuestoEducacion puestoEducacion;
	private PuestoEducacion puestoEducacionSelected;
	private boolean visibleDetalle=false;
	private List<UnidadOrganica> unidadesOrganicasSubList;
	private List<Puesto> puestosInmediatos;
	
	@Inject
	private ParametroMB parametro;
	
	@Inject
	private SigerhService service;
	
	public PuestoUnidadMB() {
		// TODO Auto-generated constructor stub
	}
	
	@PostConstruct
	public void inicio(){
		unidadesOrganicasList=service.listarUnidadesOrganicas();
		generarArbolJerarquico();
		if(unidadesOrganicasList.size()>0){
		uoSelected=unidadesOrganicasList.get(0);
		System.out.println("selected uo:"+uoSelected);
		cargarPuestosInmediatos();
		loadArbolJerarquicoPuesto();
		}
		nuevo();
		puestoEducacion=new PuestoEducacion();
		puestoEducacion.setEstudio(new CondicionEstudio());
		puestoEducacion.setNivel(new AdmGrado());
	}
	
	public DefaultTreeNode getArbolUO() {
		return arbolUO;
	}

	public void setArbolUO(DefaultTreeNode arbol) {
		this.arbolUO = arbol;
	}

	public void nuevo(){
		puestoSelected=new Puesto();
		puestoSelected.setSuperiorInmediato(new Puesto());
		puestoSelected.setIdCargo(new Cargo());
		puestoSelected.setIdUnidadOrganica(uoSelected);
		puestoSelected.setIdPuestoAnalisis(new PuestoAnalisis());
		puestoSelected.getIdPuestoAnalisis().setPuestoCapacitacionList(new ArrayList<PuestoCapacitacion>());
		puestoSelected.getIdPuestoAnalisis().setPuestoEducacionList(new ArrayList<PuestoEducacion>());
		puestoSelected.setPuestoCab(new PuestoCabecera());
		puestoEducacion=new PuestoEducacion();
		puestoEducacion.setEstudio(new CondicionEstudio());
		puestoEducacion.setNivel(new AdmGrado());
		mision="";
		funciones="";
		nroHojaInformativa="";
		
	}
	
	private void generarArbolJerarquico(){
		arbolUO=new DefaultTreeNode("Root",null);
		TreeNode[] listaTemp=new DefaultTreeNode[unidadesOrganicasList.size()];
		int idx=0;
		//creamos todos los nodos sueltos
		for(UnidadOrganica uo : unidadesOrganicasList ){
			TreeNode nodo=new DefaultTreeNode(uo,arbolUO);
			listaTemp[idx++]=nodo;
		}
		//actualizamos su jerarquia
		for(int i=0;i<listaTemp.length;i++){
			TreeNode n= hallarNodoParent((UnidadOrganica)listaTemp[i].getData(), listaTemp);
			listaTemp[i].setParent(n);
			
		}
		
	}
	
	private TreeNode hallarNodoParent(UnidadOrganica uo,TreeNode[] nodo){
		TreeNode nodoBuscado=arbolUO;//por default sera arbol root
		for(TreeNode node :nodo){
			if(node.getData().equals(uo.getDepende())){
				nodoBuscado= node;
				//System.out.println("ok hallado padre de "+uo.getSiglas() +" de "+uo.getDepende().getSiglas());
				break;
			}
		}
		return nodoBuscado;
	}

	private TreeNode hallarNodoParentPuesto(Puesto uo,TreeNode[] nodo){
		TreeNode nodoBuscado=arbolPuestosUO;//por default sera arbol root
		for(TreeNode node :nodo){
			if(node.getData().equals(uo.getSuperiorInmediato())){
				nodoBuscado= node;
				//System.out.println("ok hallado padre de "+uo.getSiglas() +" de "+uo.getDepende().getSiglas());
				break;
			}
		}
		return nodoBuscado;
	}
	public TreeNode getNodeUOSelected() {
		return nodeUOSelected;
	}

	public void setNodeUOSelected(TreeNode nodeSelected) {
		this.nodeUOSelected = nodeSelected;
	}

	public Puesto getPuestoSelected() {
		return puestoSelected;
	}

	public void setPuestoSelected(Puesto puestoSelected) {
		this.puestoSelected = puestoSelected;
	}

	public String getMision() {
		return mision;
	}

	public void setMision(String mision) {
		this.mision = mision;
	}

	public String getFunciones() {
		return funciones;
	}

	public void setFunciones(String funciones) {
		this.funciones = funciones;
	}

	public String getNroHojaInformativa() {
		return nroHojaInformativa;
	}

	public void setNroHojaInformativa(String nroHojaInformativa) {
		this.nroHojaInformativa = nroHojaInformativa;
	}

	public UnidadOrganica getUoSelected() {
		return uoSelected;
	}

	public void setUoSelected(UnidadOrganica uoSelected) {
		this.uoSelected = uoSelected;
	}

	public DefaultTreeNode getArbolPuestosUO() {
		return arbolPuestosUO;
	}

	public void setArbolPuestosUO(DefaultTreeNode arbolPuestosUO) {
		this.arbolPuestosUO = arbolPuestosUO;
	}

	public List<Puesto> getPuestosInmediatos() {
		return puestosInmediatos;
	}

	public void setPuestosInmediatos(List<Puesto> puestosInmediatos) {
		this.puestosInmediatos = puestosInmediatos;
	}

	public boolean isDisponibilidadViaje() {
		return disponibilidadViaje;
	}

	public void setDisponibilidadViaje(boolean disponibilidadViaje) {
		this.disponibilidadViaje = disponibilidadViaje;
	}
	
	public void onNodeUOSelect(NodeSelectEvent event) {  
		uoSelected=(UnidadOrganica)event.getTreeNode().getData();
		uoSelected=service.obtenerUnidadOrganica(uoSelected.getIdUnidadOrganica());
		cargarPuestosInmediatos();
		loadArbolJerarquicoPuesto();
    }  
	public void onNodePuestoSelect(NodeSelectEvent event) {  
		puestoEdicionSelected=(Puesto)event.getTreeNode().getData();
		reloadPuestoEdicionSelected();
		Puesto superior=puestoEdicionSelected.getSuperiorInmediato();
		if(superior==null){
			puestoEdicionSelected.setSuperiorInmediato(new Puesto());
		}
		
		
    } 
	
	private void loadArbolJerarquicoPuesto(){
		List<Puesto> puestos=service.listarPuestosPorUnidadOrganica(uoSelected.getIdUnidadOrganica());
		arbolPuestosUO=new DefaultTreeNode("Root",null);
		TreeNode[] listaTemp=new DefaultTreeNode[puestos.size()];
		int idx=0;
		//creamos todos los nodos sueltos
		for(Puesto p : puestos ){
			TreeNode nodo=new DefaultTreeNode(p,arbolPuestosUO);
			listaTemp[idx++]=nodo;
		}
		//actualizamos su jerarquia
		for(int i=0;i<listaTemp.length;i++){
			TreeNode n= hallarNodoParentPuesto((Puesto)listaTemp[i].getData(), listaTemp);
			listaTemp[i].setParent(n);
		}
		
		selectPuestoByDefault();
	}
	
	public void addEstudioNuevoPuesto(){
		if(verificarExiste(puestoEducacion,puestoSelected)){
			Utilitario.mostrarMensajeAlerta("Los requisitos de educacion ya existe para este puesto");
			return;
			
		}
		
		
		for (SelectItem s:parametro.getCondicionEstudios()){
			if(s.getValue().equals(puestoEducacion.getEstudio().getIdCondEstudio())){
				puestoEducacion.getEstudio().setDenominacion(s.getLabel());
				break;
			}
		}
		
		for (SelectItem s:parametro.getGradosAcademicos()){
			if(s.getValue().equals(puestoEducacion.getNivel().getIdAdmGrado())){
				puestoEducacion.getNivel().setDenominacion(s.getLabel());
				break;
			}
		}
		//id unico temporal
		puestoEducacion.setIdPuestoEducacion(new Integer(puestoEducacion.getEstudio().getIdCondEstudio()+""+puestoEducacion.getNivel().getIdAdmGrado()));
		puestoSelected.getIdPuestoAnalisis().getPuestoEducacionList().add(puestoEducacion);
		puestoEducacion=new PuestoEducacion();
		puestoEducacion.setEstudio(new CondicionEstudio());
		puestoEducacion.setNivel(new AdmGrado());
	}
	
public void quitarPuestoEducacion(){
	int idx=0;
	for(PuestoEducacion pe:puestoSelected.getIdPuestoAnalisis().getPuestoEducacionList()){
		System.out.println("comparando :"+pe.getIdPuestoEducacion()+"=="+puestoEducacionSelected.getIdPuestoEducacion());
		if(pe.getIdPuestoEducacion()==puestoEducacionSelected.getIdPuestoEducacion()){
			System.out.println("hallado en el indice "+idx);
			break;
		}
		idx++;
	}
	puestoSelected.getIdPuestoAnalisis().getPuestoEducacionList().remove(idx);
}
	
public void registrar(){
	try {
		System.out.println("llamado a registrar");
		if(puestoSelected.getIdPuestoAnalisis().getPuestoEducacionList().size()==0){
			Utilitario.mostrarMensajeAlerta("Debe Ingresar al menos una profesion y nivel de estudios requerida para este puesto");
			return;
		}
		puestoSelected.getIdPuestoAnalisis().setDispViaje(disponibilidadViaje?"S":"N");
		puestoSelected.getIdPuestoAnalisis().setFunciones(funciones);
		puestoSelected.getIdPuestoAnalisis().setMision(mision);
		puestoSelected= service.registrarPuesto(puestoSelected);
		loadArbolJerarquicoPuesto();
		Utilitario.mostrarMensajeExito("El registro del puesto fue satisfactorio");
		
	} catch (Exception e) {
		// TODO: handle exception
		Utilitario.mostrarMensajeAlerta("No se pudo registrar el puesto :"+e.getMessage());
	}
	
}	
	
public TreeNode getNodePuestoSelected() {
	return nodePuestoSelected;
}

public void setNodePuestoSelected(TreeNode nodePuestoSelected) {
	this.nodePuestoSelected = nodePuestoSelected;
}

public PuestoEducacion getPuestoEducacion() {
	return puestoEducacion;
}

public void setPuestoEducacion(PuestoEducacion puestoEducacion) {
	this.puestoEducacion = puestoEducacion;
}

public PuestoEducacion getPuestoEducacionSelected() {
	return puestoEducacionSelected;
}

public void setPuestoEducacionSelected(PuestoEducacion puestoEducacionSelected) {
	this.puestoEducacionSelected = puestoEducacionSelected;
}

public boolean isVisibleDetalle() {
	visibleDetalle=arbolPuestosUO.getChildCount()==0?false:true;
	return visibleDetalle;
}

public void setVisibleDetalle(boolean visibleDetalle) {
	this.visibleDetalle = visibleDetalle;
}

public List<UnidadOrganica> getUnidadesOrganicasSubList() {
	return unidadesOrganicasSubList;
}

public void setUnidadesOrganicasSubList(List<UnidadOrganica> unidadesOrganicasSubList) {
	this.unidadesOrganicasSubList = unidadesOrganicasSubList;
}

private void selectPuestoByDefault(){
	if(arbolPuestosUO.getChildCount()>0){
		puestoEdicionSelected=(Puesto)arbolPuestosUO.getChildren().get(0).getData();
		reloadPuestoEdicionSelected();
		Puesto superior=puestoEdicionSelected.getSuperiorInmediato();
		if(superior==null){
			puestoEdicionSelected.setSuperiorInmediato(new Puesto());
		}
	}
	else
		nuevo();
	
}

public Puesto getPuestoEdicionSelected() {
	return puestoEdicionSelected;
}

public void setPuestoEdicionSelected(Puesto puestoEdicionSelected) {
	this.puestoEdicionSelected = puestoEdicionSelected;
}

public void updatePuesto(){
	try {
	service.actualizarPuesto(puestoEdicionSelected);
	Utilitario.mostrarMensajeExito("La operacion se realizo satisfactoriamente");
	//reloadPuestoEdicionSelected();
	} catch (Exception e) {
		// TODO: handle exception
	Utilitario.mostrarMensajeAlerta("Ocurrio un error al actualizar el registro "+e.getMessage());
	}

}


public void updateEstudioPuesto(){
	try {
	System.out.println("colocando el puesto analisis antes de verificar si existe "+puestoEdicionSelected.getIdPuestoAnalisis());
	if(verificarExiste(puestoEducacion,puestoEdicionSelected)){
		Utilitario.mostrarMensajeAlerta("Los requisitos de educacion ya existe para este puesto");
		return;
		
	}
	
	
	puestoEducacion.setPuestoAnalisis(puestoEdicionSelected.getIdPuestoAnalisis());
	service.actualizarPuestoEducacion(puestoEducacion);
	Utilitario.mostrarMensajeExito("La operacion se realizo satisfactoriamente");
	reloadPuestoEdicionSelected();
	} catch (Exception e) {
		// TODO: handle exception
	Utilitario.mostrarMensajeAlerta("Ocurrio un error al actualizar el registro "+e.getMessage());
	}

}

private boolean verificarExiste(PuestoEducacion p, Puesto puesto){
	for(PuestoEducacion pe: puesto.getIdPuestoAnalisis().getPuestoEducacionList())
	{
		if(pe.getEstudio().getIdCondEstudio()==p.getEstudio().getIdCondEstudio()&& pe.getNivel().getIdAdmGrado()==p.getNivel().getIdAdmGrado()){
			return true;
		}
	}
	
	return false;
}

public void eliminarEstudioPuesto(){
	try {
		service.eliminarPuestoEducacion(puestoEducacionSelected);
		Utilitario.mostrarMensajeExito("La operacion se realizo satisfactoriamente");
		reloadPuestoEdicionSelected();
		} catch (Exception e) {
			// TODO: handle exception
			Utilitario.mostrarMensajeAlerta("Ocurrio un error al eliminar el registro "+e.getMessage());
		}
	
}

private void reloadPuestoEdicionSelected(){
	System.out.println("recargando el puesto selected");
	puestoEdicionSelected=service.obtenerPuesto(puestoEdicionSelected.getIdPuesto());
	System.out.println(puestoEdicionSelected.getIdPuestoAnalisis().getPuestoEducacionList());
	if(puestoEdicionSelected.getSuperiorInmediato()==null)
		puestoEdicionSelected.setSuperiorInmediato(new Puesto());
}

private void cargarPuestosInmediatos(){
	puestosInmediatos=new ArrayList<Puesto>();
	puestosInmediatos=service.listarPuestosPorUnidadOrganica(uoSelected.getIdUnidadOrganica());
	if(uoSelected.getDepende()!=null){
	puestosInmediatos.addAll(service.listarPuestosPorUnidadOrganica(uoSelected.getDepende().getIdUnidadOrganica()));
	}
}
}
